Skip to content

fix(AssetController): refactor Snap data source#7764

Merged
Kriys94 merged 3 commits intomainfrom
fix/CleanSnapDataSource
Feb 2, 2026
Merged

fix(AssetController): refactor Snap data source#7764
Kriys94 merged 3 commits intomainfrom
fix/CleanSnapDataSource

Conversation

@Kriys94
Copy link
Copy Markdown
Contributor

@Kriys94 Kriys94 commented Jan 28, 2026

Explanation

This PR simplifies and cleans up SnapDataSource by:

  1. Dynamic snap discovery via PermissionController: Instead of hardcoded snap registry entries, SnapDataSource now dynamically discovers installed snaps that have the endowment:keyring permission and extracts their supported chain IDs from permission caveats. This makes the data source more flexible and extensible for future snaps.

  2. Simplified fetch routing: Changed from complex chain-based routing to account-based routing using account.metadata.snap.id. This aligns with how MultichainBalancesController handles snap accounts and is more direct since each account already knows which snap it belongs to.

  3. Added KeyringClient: Replaced manual SnapController:handleRequest calls with KeyringClient from @metamask/keyring-snap-client, which provides cleaner typed methods (listAccountAssets, getAccountBalances). This follows the same pattern used in MultichainBalancesController.

  4. Removed unused/redundant code:

    • Removed DEFAULT_SNAP_POLL_INTERVAL constant (never used)
    • Removed #groupChainsBySnapId method (no longer needed with account-based routing)
    • Removed #fetchFromSnapById method (inlined into fetch)
    • Removed #accountSupportsChain method (unused after simplification)
    • Removed redundant chain filtering in fetch (already done by middleware/subscribe callers)
    • Removed unused InternalAccount import
  5. Used proper types: Replaced inline type Record<string, { amount: string; unit: string }> with GetAccountBalancesResponse and Balance from @metamask/keyring-api.

Dependencies added:

  • @metamask/keyring-api: For Balance and CaipAssetType types
  • @metamask/keyring-snap-client: For KeyringClient to make typed snap calls

References

  • Related to the SnapDataSource dynamic snap discovery refactoring
  • Pattern aligned with MultichainBalancesController and MultichainAssetsController implementations

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

High Risk
High risk because it changes SnapDataSource discovery/routing behavior and removes the snapProvider dependency and many exported constants/types, which may break consumers and alter which chains/accounts get queried for balances.

Overview
Refactors SnapDataSource to use dynamic snap discovery instead of a hardcoded Solana/Bitcoin/Tron registry: it now queries SnapController:getRunnableSnaps and PermissionController:getPermissions to build a chainToSnap map from the endowment:assets chainIds caveat, and keeps activeChains empty until discovery succeeds (re-running on PermissionController:stateChange).

Simplifies balance fetching to be account-driven by using account.metadata.snap.id and calling snap keyring methods via KeyringClient (@metamask/keyring-snap-client) over SnapController:handleRequest, plus updates event filtering and cleanup/unsubscribe logic accordingly.

Updates initialization to delegate the new Snap/Permission controller actions/events, removes snapProvider from initDataSources options/tests, trims Snap exports from index.ts, and adds new dependencies/tsconfig references for permission/keyring snap support.

Written by Cursor Bugbot for commit 0376a35. This will update automatically on new commits. Configure here.

@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch 2 times, most recently from 7238184 to 58befda Compare January 29, 2026 10:34
@Kriys94 Kriys94 marked this pull request as ready for review January 29, 2026 10:41
@Kriys94 Kriys94 requested review from a team as code owners January 29, 2026 10:41
@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch from 58befda to edad4fe Compare January 29, 2026 10:43
Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts
Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts Outdated
Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts
Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts Outdated
Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts Outdated
Comment on lines +509 to +511
const snapSupportsRequestedChains = request.chainIds.some(
(chainId) => this.state.chainToSnap[chainId] === snapId,
);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand how this is supposed to work. What if the chainToSnap mapping isn't already populated? Are the inputs BIP-44 account groups or individual accounts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chainToSnap is populated at the initialization of MetaMask, much before that we are fetching assets. So What if the chainToSnap mapping isn't already populated? is unlikely to say impossible.

Are the inputs BIP-44 account groups or individual accounts?
request.accounts is the selected account group

@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch from edad4fe to b6be0e0 Compare January 29, 2026 13:10
Comment thread packages/assets-controller/src/data-sources/initDataSources.ts Outdated
@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch 3 times, most recently from bbc3ea1 to 92d01fb Compare January 29, 2026 14:45
Copy link
Copy Markdown
Contributor

@Prithpal-Sooriya Prithpal-Sooriya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving on first pass. This data source is completely new and not in production (we have time to refine).

Lets have the snaps team to review before merging. Maybe a short loom/recording to walkthrough changes?

Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts Outdated
Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts Outdated
const configuredNetworks =
options.configuredNetworks ?? ALL_DEFAULT_NETWORKS;

super(SNAP_DATA_SOURCE_NAME, {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily Snaps-related, but I think you should loop in @mcmire to look at the DataSource architecture. We should ensure that this pattern is aligned with the approach we generally want for data services.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@FrederikBolding: Thanks for the mention, @Kriys94 messaged me privately about the DataSource code in AssetsController code. I'm looking through it now to understand how it all fits together. @Kriys94: I'll let you know when I have something to share.

Copy link
Copy Markdown
Contributor Author

@Kriys94 Kriys94 Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a diagram about what we are trying to build https://consensyssoftware.atlassian.net/wiki/spaces/PRDC/pages/400284352527/Architecture+proposal+34+AssetsController+the+cross-network-asset-type+controller#High-Level-Architecture

Here we call "data source" a piece of logic that extends the AssetsController and implements a specific interface to work with external services (Backend REST APIs, Snap, RPC). The code is related to the business logic, here assets balance, price and metadata.

For @mcmire and this ticket https://consensyssoftware.atlassian.net/browse/WPC-26, I think it refers more to a new service/client I just implemented in core-backend https://github.com/MetaMask/core/tree/main/packages/core-backend#http-api . The code in core-backend is agnostic form business logic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case, feel free to comment on the overall code :) It's not released yet so making a braking change is easy :)

Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts Outdated
Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts
Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts
Comment thread packages/assets-controller/src/data-sources/initDataSources.ts
@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch from 82d66c0 to 1d3ed84 Compare January 30, 2026 19:04
@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch from 1d3ed84 to ad81bb1 Compare January 30, 2026 19:20
Comment thread packages/assets-controller/package.json
Comment on lines +762 to +765
const cachedClient = this.#keyringClientCache.get(snapId);
if (cachedClient) {
return cachedClient;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

FrederikBolding
FrederikBolding previously approved these changes Feb 2, 2026
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Comment thread yarn.lock
Comment thread packages/assets-controller/src/data-sources/SnapDataSource.ts
@Kriys94 Kriys94 added this pull request to the merge queue Feb 2, 2026
Merged via the queue into main with commit 297e96e Feb 2, 2026
302 checks passed
@Kriys94 Kriys94 deleted the fix/CleanSnapDataSource branch February 2, 2026 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants